use std::{hint::black_box, mem};

use criterion::Criterion;
use cs2s::{
    cache::{CacheTableKey, CacheTableKeyRef},
    command::{Command, CommandKind},
    sign::CodeSign,
    utils::map::Key,
};

pub fn construction(c: &mut Criterion) {
    const MSG_SIZE_MAX: usize = 32768;
    const DUMMY: [u8; 1] = [0u8];

    let sign: CodeSign = DUMMY.into();

    c.bench_function("construct sync min size", |b| {
        b.iter(|| {
            let result = Command::new(CommandKind::Synchronize {
                path_len: DUMMY.len(),
                cache_key: CacheTableKey::from_ref(&CacheTableKeyRef {
                    guest_addr: 0x400000,
                    guest_size: DUMMY.len(),
                    guest_sign: &sign,
                }),
                host_meta_size: DUMMY.len(),
                host_code_size: DUMMY.len(),
            })
            .with_payload(MSG_SIZE_MAX, [DUMMY, DUMMY, DUMMY])
            .unwrap();
            black_box(result)
        })
    });

    c.bench_function("construct sync max size", |b| {
        b.iter(|| {
            const REST: usize =
                MSG_SIZE_MAX - mem::size_of::<Command>() - DUMMY.len() - DUMMY.len();

            let result = Command::new(CommandKind::Synchronize {
                path_len: DUMMY.len(),
                cache_key: CacheTableKey::from_ref(&CacheTableKeyRef {
                    guest_addr: 0x400000,
                    guest_size: DUMMY.len(),
                    guest_sign: &sign,
                }),
                host_meta_size: DUMMY.len(),
                host_code_size: REST,
            })
            .with_payload(
                MSG_SIZE_MAX,
                [DUMMY.as_ref(), DUMMY.as_ref(), [0u8; REST].as_ref()],
            )
            .unwrap();
            black_box(result)
        })
    });
}
